#include "ModbusManager.h"

#include <QDebug>

#include "ConfigManager.h"

// 初始化静态成员
ModbusManager* ModbusManager::m_instance = nullptr;
QRecursiveMutex ModbusManager::m_instanceMutex;

ModbusManager* ModbusManager::instance()
{
    if (!m_instance) {
        QMutexLocker locker(&m_instanceMutex);
        if (!m_instance) {
            m_instance = new ModbusManager();
            // 自动加载配置
            m_instance->loadConfiguration();
        }
    }
    return m_instance;
}

void ModbusManager::destroy()
{
    QMutexLocker locker(&m_instanceMutex);
    if (m_instance) {
        // 自动保存配置
        m_instance->saveConfiguration();
        delete m_instance;
        m_instance = nullptr;
    }
}

ModbusManager::ModbusManager(QObject* parent) : QObject(parent)
{
    qDebug() << "ModbusManager instance created";
}

ModbusManager::~ModbusManager()
{
    // 清理所有活动连接
    QMutexLocker locker(&m_mutex);
    for (auto it = m_activeDevices.begin(); it != m_activeDevices.end(); ++it) {
        delete it.value();
    }
    m_activeDevices.clear();
    qDebug() << "ModbusManager instance destroyed";
}

void ModbusManager::addDevice(const QString& deviceId, const MbDeviceConfig& config)
{
    QMutexLocker locker(&m_mutex);
    if (!m_deviceConfigs.contains(deviceId)) {
        m_deviceConfigs.insert(deviceId, config);
        if (config.enabled) {
            enableDevice(deviceId);
        }
        qDebug() << "Added device configuration:" << deviceId << config.name;
    } else {
        updateDeviceConfig(deviceId, config);
    }
}

void ModbusManager::removeDevice(const QString& deviceId)
{
    QMutexLocker locker(&m_mutex);

    // 如果设备处于活动状态，先禁用它
    if (m_activeDevices.contains(deviceId)) {
        ModbusHelper* helper = m_activeDevices.take(deviceId);
        delete helper;
        qDebug() << "Removed active device:" << deviceId;
    }

    // 移除配置
    if (m_deviceConfigs.contains(deviceId)) {
        m_deviceConfigs.remove(deviceId);
        qDebug() << "Removed device configuration:" << deviceId;
    }
}

bool ModbusManager::enableDevice(const QString& deviceId)
{
    QMutexLocker locker(&m_mutex);

    // 检查设备是否已配置
    if (!m_deviceConfigs.contains(deviceId)) {
        qDebug() << "Cannot enable device - ID not found:" << deviceId;
        return false;
    }

    // 如果设备已经启用，直接返回成功
    if (m_activeDevices.contains(deviceId)) {
        qDebug() << "Device already enabled:" << deviceId;
        return true;
    }

    // 获取设备配置
    MbDeviceConfig& config = m_deviceConfigs[deviceId];

    // 创建Modbus连接
    ModbusHelper* helper = createModbusConnection(config);
    if (!helper) {
        qCritical() << "Failed to create Modbus connection for device:" << deviceId;
        emit deviceError(deviceId, "Failed to create Modbus connection");
        return false;
    }

    // 连接错误信号
    connect(
        helper, &ModbusHelper::errorOccurred, this,
        [this, deviceId](const QString& errorMessage) { onDeviceError(deviceId, errorMessage); });
    // 连接通讯成功信号
    connect(helper, &ModbusHelper::commSuccess, this,
            [this, deviceId]() { emit deviceCommSuccess(deviceId); });

    // 添加到活动设备列表
    m_activeDevices.insert(deviceId, helper);
    config.enabled = true;

    qDebug() << "Enabled device:" << deviceId;
    emit deviceStatusChanged(deviceId, true);

    return true;
}

void ModbusManager::disableDevice(const QString& deviceId)
{
    QMutexLocker locker(&m_mutex);

    if (m_activeDevices.contains(deviceId)) {
        // 获取并移除ModbusHelper
        ModbusHelper* helper = m_activeDevices.take(deviceId);

        // 更新设备状态
        if (m_deviceConfigs.contains(deviceId)) {
            m_deviceConfigs[deviceId].enabled = false;
        }

        // 释放资源
        delete helper;

        qDebug() << "Disabled device:" << deviceId;
        emit deviceStatusChanged(deviceId, false);
    } else {
        qDebug() << "Device not active, cannot disable:" << deviceId;
    }
}

void ModbusManager::updateDeviceConfig(const QString& deviceId, const MbDeviceConfig& config)
{
    QMutexLocker locker(&m_mutex);

    // 如果设备当前处于活动状态，需要先禁用它
    if (m_activeDevices.contains(deviceId)) {
        disableDevice(deviceId);
    }

    // 更新配置
    if (m_deviceConfigs.contains(deviceId)) {
        m_deviceConfigs[deviceId] = config;
        qDebug() << "Updated device configuration:" << deviceId;
    } else {
        m_deviceConfigs.insert(deviceId, config);
        qDebug() << "Added new device configuration:" << deviceId;
    }

    // 如果之前是启用状态，则重新启用
    if (config.enabled) {
        enableDevice(deviceId);
    }
}

ModbusHelper* ModbusManager::getModbusHelper(const QString& deviceId)
{
    QMutexLocker locker(&m_mutex);

    // if (!m_activeDevices.contains(deviceId)) {
    //     // 如果设备未启用，尝试启用它
    //     if (m_deviceConfigs.contains(deviceId) && enableDevice(deviceId)) {
    //         return m_activeDevices.value(deviceId);
    //     }
    //     return nullptr;
    // }

    return m_activeDevices.value(deviceId);
}

bool ModbusManager::isDeviceEnabled(const QString& deviceId) const
{
    QMutexLocker locker(&m_mutex);
    return m_activeDevices.contains(deviceId);
}

QStringList ModbusManager::getDeviceList() const
{
    QMutexLocker locker(&m_mutex);
    return m_deviceConfigs.keys();
}

MbDeviceConfig ModbusManager::getDeviceConfig(const QString& deviceId) const
{
    QMutexLocker locker(&m_mutex);
    if (m_deviceConfigs.contains(deviceId)) {
        return m_deviceConfigs.value(deviceId);
    }
    return MbDeviceConfig();  // 返回默认配置
}

void ModbusManager::onDeviceError(const QString& deviceId, const QString& errorMessage)
{
    QMutexLocker locker(&m_mutex);

    qDebug() << "Device error:" << deviceId << "-" << errorMessage;
    emit deviceError(deviceId, errorMessage);
}

ModbusHelper* ModbusManager::createModbusConnection(const MbDeviceConfig& config)
{
    ModbusHelper* helper = new ModbusHelper(this);
    bool success = false;

    if (config.isTCP) {
        // TCP连接
        success = helper->createModbus_tcp(config.portName, config.port, config.slaveAddress);
    } else {
        // RTU连接
        success = helper->createModbus_rtu(config.portName, config.baudRate, config.slaveAddress);
    }

    if (!success) {
        qCritical() << "Failed to create Modbus connection:" << helper->getLastError();
        delete helper;
        return nullptr;
    }

    return helper;
}

// 保存配置到文件
bool ModbusManager::saveConfiguration()
{
    QMutexLocker locker(&m_mutex);

    // 获取配置管理器实例
    ConfigManager* configMgr = ConfigManager::instance();

    // 创建设备配置节
    QJsonObject devicesObj;

    // 遍历所有设备配置
    for (auto it = m_deviceConfigs.begin(); it != m_deviceConfigs.end(); ++it) {
        QString deviceId = it.key();
        MbDeviceConfig& config = it.value();

        QJsonObject deviceObj;
        deviceObj["name"] = config.name;
        deviceObj["portName"] = config.portName;
        deviceObj["baudRate"] = config.baudRate;
        deviceObj["slaveAddress"] = config.slaveAddress;
        deviceObj["port"] = config.port;
        deviceObj["isTCP"] = config.isTCP;
        deviceObj["enabled"] = config.enabled;

        // 添加到设备配置节
        devicesObj[deviceId] = deviceObj;
    }

    // 设置配置节
    configMgr->setSection("modbus_devices", devicesObj);

    // 保存到文件
    return configMgr->saveConfig();
}

// 从文件加载配置
bool ModbusManager::loadConfiguration()
{
    QMutexLocker locker(&m_mutex);

    // 获取配置管理器实例
    ConfigManager* configMgr = ConfigManager::instance();

    // 加载配置文件（如果失败不报错，使用默认设置）
    configMgr->loadConfig();

    // 获取Modbus设备配置节
    QJsonObject devicesObj = configMgr->getSection("modbus_devices");

    // 清除现有配置
    m_deviceConfigs.clear();

    // 遍历JSON对象的所有键（即设备ID）
    for (auto it = devicesObj.begin(); it != devicesObj.end(); ++it) {
        QString deviceId = it.key();
        QJsonObject deviceObj = it.value().toObject();

        if (!deviceObj.isEmpty()) {
            MbDeviceConfig config;
            config.name = deviceObj["name"].toString();
            config.portName = deviceObj["portName"].toString();
            config.baudRate = deviceObj["baudRate"].toInt(9600);
            config.slaveAddress = deviceObj["slaveAddress"].toInt(1);
            config.port = deviceObj["port"].toInt(502);
            config.isTCP = deviceObj["isTCP"].toBool(false);
            config.enabled = deviceObj["enabled"].toBool(false);

            // 添加到设备配置映射
            m_deviceConfigs.insert(deviceId, config);

            // 如果设备配置为自动启用，则启用它
            if (config.enabled) {
                enableDevice(deviceId);
            }
        }
    }

    return true;
}